//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __SHARED_MEMORY_H__
#define __SHARED_MEMORY_H__

#include <elasys_server.h>
#include <interlocked.h>
#include "namedobj.h"

class CSharedMemory : public ISharedMemory, public NamedObject
{
public:
    CARAPI_(PInterface) Probe(
        /* [in]  */ REIID riid);

    CARAPI_(UInt32)AddRef();

    CARAPI_(UInt32)Release();

    CARAPI Aggregate(
        /* [in]  */ AggregateType type,
        /* [in]  */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface * ppObj);

    CARAPI Attach(
        /* [in]  */ MemoryProtection protect,
        /* [out] */ Address * pAddress);

    CARAPI Detach();

public:
    PInterface    GetObject() { return (PInterface) this; }
    oid_t        GetOid()    { return m_oid; }
    ObjectType GetType()   { return ObjectType_SharedMemory; }
    Boolean    CompareName(WString name);

public:
    CSharedMemory(oid_t oid)
                : m_pName(NULL),
                  m_oid(oid),
                  m_hSharedMemory(NULL),
                  m_address(0),
                  m_attachTimes(0),
                  m_hLock(NULL) { DLinkNode::Initialize(); }

    virtual ~CSharedMemory();

    ECode Initialize(
        /* [in] */ WString name,
        /* [in] */ MemorySize size,
        /* [in] */ Boolean bCommit);

private:
    WStringBuf * m_pName;
    oid_t   m_oid;
    PVoid m_hSharedMemory;

    Address m_address;
    Int32   m_attachTimes;
    PVoid   m_hLock;

private:
    Interlocked m_cRefs;
};

class CSharedMemoryFactory : public NamedObjectFactory
{
public:
    WString GetName() { return m_name; }
    ObjectType GetType() { return ObjectType_SharedMemory; }

    ECode CreateNamedObject(
            /* [out] */ NamedObject ** ppNamedObj,
            /* [out] */ Boolean * pbAlreadyExisted);

    ECode ResolveNamedObject(
            /* [in]  */ oid_t oid,
            /* [out] */ NamedObject ** ppNamedObj);

    ECode DestroyNamedObject(
            /* [in]  */ oid_t oid);
public:
    CSharedMemoryFactory(
            /* [in]  */ WString name,
            /* [in]  */ MemorySize size = 0,
            /* [in]  */ Boolean bCommit = FALSE)
            : m_name(name),
              m_size(size),
              m_bCommit(bCommit) {}
private:
    WString m_name;
    MemorySize m_size;
    Boolean m_bCommit;
};

INLINE Boolean CSharedMemory::CompareName(WString name)
{
    return m_pName->Compare(name) ? FALSE : TRUE;
}

#endif // __SHARED_MEMORY_H__

